package controller;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;

import modle.Email;

public class EmailThread extends Thread {

	private static long SLEEP_TIME = 1000 * 30 * 1;
	private Date lastCheckTime;
	private Date oldestTime;

	private Message message = null;
	List<Email> emails;
	Email email;
	boolean go = true;// control the thread

	public EmailThread(List<Email> emails) throws IOException {
		// TODO Auto-generated constructor stub
		this.emails = emails;

		Properties p = new Properties();
		InputStream ips = null;

		ips = new FileInputStream("./emailconfig.properties");
		if (ips != null) {
			p.load(ips);
			String lastTime = p.getProperty("lastCheckTime");
			lastCheckTime = new Date(Long.parseLong((lastTime)));
		} else {
			lastCheckTime = new Date(0);
		}
		oldestTime = (Date) lastCheckTime.clone();
		ips.close();
		start();
	}

	private void check(Email email) throws MessagingException {
		String host = email.getEmailPop3();
		int i = email.getEmailAddress().indexOf('@');
		if (i < 0)
			return;
		String username = email.getEmailAddress().substring(0, i);
		String password = email.getEmailPassword();
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);
		Store store = null;
		try {
			store = session.getStore("pop3");
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			store.connect(host, username, password);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Folder folder = null;
		try {
			folder = store.getFolder("INBOX");
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			folder.open(Folder.READ_ONLY);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Message messages[] = null;
		try {
			messages = folder.getMessages();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int t = 0;
		for (i = 0; i < messages.length; i++) {
			message = messages[i];
			if (isNew(message))
				t++;
		}
		if (t > 0)
			new ShowMessageThread(email.getEmailAddress() + "\nhas " + t
					+ " new Emails!\n");
		store.close();
	}

	synchronized List<Email> getEmails() {
		return emails;
	}

	public void halt() {
		go = false;
	}

	public boolean isNew(Message mes) throws MessagingException {
		if (mes.getSentDate().getTime() > oldestTime.getTime())
			oldestTime = (Date) mes.getSentDate().clone();
		if (mes.getSentDate().getTime() > lastCheckTime.getTime())
			return true;
		return false;
	}

	@Override
	public void run() {
		while (go) {
			List<Email> emails = getEmails();
			if (emails != null && !emails.isEmpty()) {
				for (int i = 0; i < emails.size(); i++) {
					email = emails.get(i);
					try {
						check(email);
					} catch (MessagingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			if (!lastCheckTime.equals(oldestTime))
				try {
					writeOldestTime();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			try {
				Thread.sleep(SLEEP_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	synchronized void setEmails(List<Email> emails) {
		this.emails = emails;
	}

	private void writeOldestTime() throws IOException {
		Properties prop = new Properties();

		OutputStream ops = new FileOutputStream("./emailconfig.properties");
		prop.setProperty("lastCheckTime", String.valueOf(oldestTime.getTime()));
		prop.store(ops, null);

		ops.close();
	}
}
